package com.cicadalane.androlate;

/*
 * Copyright (C) 2011 cicada.software@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.Bundle;

import com.cicadalane.androlate.AndrolateApplication;
import com.cicadalane.androlate.statushandlers.AndrolateStatus;

public class AndrolateWizard extends Wizard {
	private AndrolateApplication mAndrolateApplication = null;
	File mConfigFile = null;
	private LanguagePage mLanguagesPage = null;
	private LoadResourceFilesPage mLoadResourceFilesPage = null;
	IProject mProject = null;
	IPath mProjectPath = null;

	private boolean mRememberSettings = false;
	private ReviewPage mReviewPage = null;
	private StartPage mStartPage = null;

	private AndrolateWizardDialog mWizardDialog = null;
	private Bundle mBundle = Platform.getBundle(Activator.PLUGIN_ID);
	private ILog mLog = Platform.getLog(mBundle);
	private boolean mUseEclipseLog = true;

	public AndrolateWizard(IProject project) {
		super();
		mProject = project;
		mProjectPath = mProject.getLocation();
		mConfigFile = mProjectPath.append("Androlate.xml").toFile();
		AndrolateApplication.setConfigurationFile(mConfigFile);

		mAndrolateApplication = new AndrolateApplication(mProjectPath);
		GoogleTranslate.setIpAddress(AndrolateApplication.getIpAddress());
	}

	@Override
	public void addPages() {
		super.addPages();

		mStartPage = new StartPage("Welcome to Androlate");
		addPage(mStartPage);

		mLoadResourceFilesPage = new LoadResourceFilesPage("Select Resources");
		addPage(mLoadResourceFilesPage);

		mLanguagesPage = new LanguagePage("Target languages");
		addPage(mLanguagesPage);

		mReviewPage = new ReviewPage("Review actions");
		addPage(mReviewPage);
	}

	public void close() {
		if (mWizardDialog != null) {
			mWizardDialog.close();
		}
	}

	public AndrolateApplication getAndrolateApplication() {
		return mAndrolateApplication;
	}

	public File getConfigFile() {
		return mConfigFile;
	}

	public IPath getProjectPath() {
		return mProjectPath;
	}

	@Override
	public boolean needsProgressMonitor() {
		return true;
	}

	public boolean getUseEclipseLog() {
		return mUseEclipseLog;
	}

	public void setUseEclipseLog(boolean value) {
		mUseEclipseLog = value;
	}

	@Override
	public boolean performFinish() {
		String configFilename = getConfigFile().getAbsolutePath();
		if (mRememberSettings) {
			try {
				mAndrolateApplication.saveFile(configFilename);
			} catch (Exception e) {
				Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
						AndrolateStatus.ERROR_SAVE_CONFIG, e.getMessage(), e
								.getCause());
				mLog.log(status);
				StatusManager.getManager().handle(status, StatusManager.BLOCK);
				close();
				return false;
			}
		} else {
			if (getConfigFile().exists())
				try {
					getConfigFile().delete();
				} catch (Exception ignored) {
					ignored = null;
				}
		}

		// refresh the project to reflect the new config file
		try {
			mProject.refreshLocal(IProject.DEPTH_INFINITE, null);
		} catch (CoreException ce) {
			// ignored
		}

		try {
			getContainer().run(true, true, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor) {
					try {
						Androlate a = mAndrolateApplication.getAndrolate();
						ArrayList<StringData> resolvedStringList = mAndrolateApplication
								.resolveStringOperations(a);
						int translateOperationsCount = resolvedStringList
								.size()
								* a.getTargetLanguages().size();
						monitor.beginTask("Translating : ",
								translateOperationsCount);
						for (AndrolateLanguage l : a.getTargetLanguages()) {
							monitor.subTask(l.getDisplay());
							for (AndrolateOperation o : a.getOperations()) {
								try {
									if (monitor.isCanceled()) {
										return;
									}
									mAndrolateApplication.TranslateOperation(o,
											l, resolvedStringList, monitor);
								} catch (final Exception e) {
									Display.getDefault().asyncExec(
											new Runnable() {
												@Override
												public void run() {
													Status status = new Status(
															IStatus.WARNING,
															Activator.PLUGIN_ID,
															AndrolateStatus.WARN_INVOCATION_EXCEPTION,
															"Translate Error, your resources may be out of sync " + e.getMessage(),
															e.getCause());
													if (mUseEclipseLog)
														mLog.log(status);
													StatusManager
															.getManager()
															.handle(
																	status,
																	StatusManager.BLOCK);
												}
											});
								}
							}
							monitor.worked(1);
						}
					} finally {
						monitor.done();
					}
				}
			});
		} catch (InvocationTargetException e) {
			Status status = new Status(
					IStatus.WARNING,
					Activator.PLUGIN_ID,
					AndrolateStatus.WARN_INVOCATION_EXCEPTION,
					"InvocationTargetException Translation was interuppted, your resources may be out of sync",
					e.getCause());
			mLog.log(status);
			StatusManager.getManager().handle(status, StatusManager.BLOCK);
		} catch (InterruptedException e) {
			Status status = new Status(
					IStatus.WARNING,
					Activator.PLUGIN_ID,
					AndrolateStatus.WARN_INTERRUPTION_EXCEPTION,
					"InvocationTargetException Translation was interuppted, your resources may be out of sync",
					e.getCause());
			mLog.log(status);
			StatusManager.getManager().handle(status, StatusManager.BLOCK);
		}

		// refresh the project to reflect the new config file
		try {
			mProject.refreshLocal(IProject.DEPTH_INFINITE, null);
		} catch (CoreException ce) {
			// ignored
		}

		return true;
	}


	protected void setAndrolateWizardDialog(AndrolateWizardDialog dialog) {
		mWizardDialog = dialog;
	}

	public void setRememberSettingsOption(boolean value) {
		mRememberSettings = value;
	}

}
